#include "SZNR/SZNRAsduParser.h"

#include <QDebug>
#include "utils.h"
#include <QMapIterator>
#include <QMap>

SZNRAsduParser::SZNRAsduParser()
{
    // 确认定值组组号 03

    // 初始化成员变量 m_billValueGroup
    m_billValueGroupsNo << "2" << "3";
}

SZNRAsduParser::~SZNRAsduParser()
{
}

bool SZNRAsduParser::parseRecvPacket(const QByteArray &pData, int packetLength)
{
    QByteArray packet = pData;
    Utils::washPacket(packet);
    if (packetLength > 14)  // 最小长度14，无数据的情况下可变帧长数据
    {
        parseVariableData(packet);
    }
    else    // 固定帧长报文
    {
        qDebug() << "not ASDU10 ";
    }

    return true;
}

void SZNRAsduParser::parseASDU10(const QByteArray &packet)
{
    int fun = packet.mid(FUN_POSI_NZ, 2).toUInt(nullptr,16);
    int inf = packet.mid(INF_POSI_NZ, 2).toUInt(nullptr,16);

    // 1. 通用分类数据响应命令
    if (FUN_GEN == fun && 0xF0 == inf) //通用分类数据响应命令（装置响应的读目录）
    {

    }

    // 2. 读指定定值组的所有条目的响应，中文名称，值，缺省值，最大最小值，步长，单位
    if ( FUN_GEN == fun && 0xF0 == inf )
    {
        parseASDU10AllValue(packet);
    }
    // 3. 读指定一个条目的描述或者值
    else if ( FUN_GEN == fun && INF_READ_GROUP == inf )
    {
        parseASDU10AllValue(packet);
    }
    else if ( FUN_GEN == fun && INF_READ_EBTRY == inf )   // 带确认的写条目响应
    {
        parseASDU10AllValue(packet);
    }
    else if ( FUN_GEN == fun && INF_EXEC_WRITE == inf ) // 带执行的写条目响应
    {
        QString rii = packet.mid(RII_POSI_NZ,2);
    }
    else
    {
        qDebug() << "unknow asdu10: "<<packet;

    }

    return;
}

bool SZNRAsduParser::parseVariableData(const QByteArray &pData)
{
    QString asduType = pData.mid(0,2); // asdu类型

    switch(asduType.toUInt(nullptr,16))        // 设备回主站都是 OA 开头的回答服务
    {
        case ASDU_10:
            parseASDU10(pData);
            break;
        default:
            break;
    }

    return true;
}

vector<OneDataSetStruct> SZNRAsduParser::parseASDU10AllValue(const QByteArray &packet)
{
    // 类型标识
    QString typeID = packet.mid(0,2);

    // 解析报文头，前7个字节
    QString ngd=packet.mid(14,2);  // 通用分类数据集数目，表示后面有多少个数据
    uint8_t ngd_int =  Utils::calNgdNo(ngd);
    QString dataArea = packet.mid(16);   //从第8个开始截取报文的全部数据集元素

    qDebug() << "全部的报文数据为: " << packet;
    qDebug() << "全部的数据集为：  " <<dataArea;

    // 解析用户数据段
    // 1.组号，2.条目号，3.描述类别，4.数据类型，5.数据宽度，6.数目，7.数据
    // 整个数据的长度 = 6*2 + 【数值长度】，数据宽度值等于数据长度 ， 数据宽度 * 数目

    int dataOffset = 0;     // 每一个数据的宽度都可能不一样
    vector<OneDataSetStruct> allData;        // 需要返回的数据
    OneDataSetStruct tmpDataSet;
    qDebug() << " ngd 16进制 = " << ngd_int;        // 数据集元素个数
    for (int i=0; i<ngd_int; i++)
    {
        tmpDataSet.m_ginGroup = dataArea.mid(dataOffset, 2);
        tmpDataSet.m_ginNo = dataArea.mid(dataOffset + 2, 2);
        tmpDataSet.m_kod = dataArea.mid(dataOffset + 4, 2);   //每一个数据占的字节数据
        //qDebug() << "the kod =  " << dataArea.mid(dataOffset + 4, 2);
        tmpDataSet.m_dataType = dataArea.mid(dataOffset + 6, 2);
        tmpDataSet.m_dataWidth = dataArea.mid(dataOffset + 8, 2);
        tmpDataSet.m_dataNum = dataArea.mid(dataOffset + 10, 2);

        //分析数据类型
        tmpDataSet.m_dataValue = dataArea.mid(dataOffset + 12, 2* tmpDataSet.m_dataNum.toInt(nullptr,16) * tmpDataSet.m_dataWidth.toInt(nullptr,16));
        allData.push_back(tmpDataSet);

        dataOffset = dataOffset + ( 12 + 2 * tmpDataSet.m_dataNum.toInt(nullptr,16) * tmpDataSet.m_dataWidth.toInt(nullptr,16) );
    }

    //showDataSets(allData);

    return allData;
}

 // 解析接收的报文
int SZNRAsduParser::recvPacketTypeFilter(const QByteArray &packet)
{
    // 对报文返回进行判断 , 1.返回信息标识符号相同 2.有效数据恢复cot=2A 3.是通用服务 4.信息序号是一个组的”F1“值或属性描述
    int type = -3;
    QString asduType = packet.mid(0,2);
    QString fun = packet.mid(POS_ASDU_FUN, 2);
    QString inf = packet.mid(POS_ASDU_INF, 2);
    QString rii = packet.mid(POS_ASDU_RII, 2);
    QString cot = packet.mid(POS_ASDU_COT, 2);
    QString ngd = packet.mid(POS_ASDU_NGD, 2);     // 数据集元素的个数，读定值区时只有一个值， 定值组布置一个定值
    QString groupNo = packet.mid(POS_ASDU_GROUPNO, 2);
    // 确认是否是通用分类读的有效响应

    qDebug() << "待解析的asdu基本信息 "<< asduType << cot << fun;


    if ( asduType.toLower() == "0a"  && (cot.toLower() == COT_S2C_GENERAL_READ_STR || cot.toLower() == COT_S2C_CIRCLE_SEND_STR) && fun.toLower() =="fe")
    {
        qDebug() << "有效数据响应。。。。";
        if ( inf.toLower() == "f1" )   // 是对一个组的读取操作
        {
            qDebug() << "对读指定组的有效数据响应。。。。";
            QString kod = packet.mid(20,2).toUpper();
            if ( kod == KOD_DESCRIPTER )
            {
                type = REPLY_READ_SETTINGS_NAME;
            }
            else if ( kod == KOD_REAL_VALUE )
            {
                qDebug() << "读实际值的响应" << "组号 = " << QString::number(groupNo.toUInt(nullptr,16));
                if ( QString::number(groupNo.toUInt(nullptr,16)) == m_deviceSysGroupNo && ngd == "01" )    // 是系统参数组中定值区的实际值,这个 “00" 应该是在读取标题时候确认的
                {
                    type = REPLY_READ_SETTINGS_AREA;
                    qDebug () << "读取定值区号的实际值";
                }
                //读压板组的实际值
                else if ( QString::number(groupNo.toUInt(nullptr,16)) == m_ybGroupNo )           // 实际"OE", 由读全部组的标题来确认组号哪个是压板组，哪个是定值组
                {
                    type = REPLY_READ_YB;
                }
                // 判断是读定值组的实际值
                else if (m_billValueGroupsNo.contains(QString::number(groupNo.toUInt(nullptr, 16))))
                {
                    qDebug () << "读取定值的实际值";
                      // 是读的定值组的全部的值
                    type = REPLY_READ_SETTINGS_CURRVALUE;
                }
            }
            else if ( kod == KOD_DEFAULT_VALU )
            {
                type = REPLY_READ_DEFAULTVALUE;
            }
            else if ( kod == KOD_DIMENSION )
            {
                type = REPLY_READ_SETTINGS_MIN;
            }
            else if ( kod == KOD_UNIT )
            {
                type = REPLY_READ_SETTINGS_UNIT;
            }
            else {
                type = -3;
            }
        }
        else if ( inf == "F0" )    // 只读全部组的标题
        {
            type = REPLY_TYPE_ALL_GROUP_TITLE;
        }
    }

    return  type;
}

QStringList SZNRAsduParser::parseBillValueNames(const QByteArray &packet)
{
    QStringList names;

    // 解析接收的报文
    SZNRAsduParser parser;
    vector<OneDataSetStruct> dataSets = parser.parseASDU10AllValue(packet);
    QString billValueGroup = "03";
    foreach (OneDataSetStruct it, dataSets)
    {
        // 定值的名称描述,确认读的组号
     //   if ( m_billValueGroups.contains(it.m_ginGroup) /*&&  it.m_kod == "0A"*/)
        {
            // qDebug() << "组号 " << it.m_ginGroup.toInt(nullptr,16) << ", 汉字表示： "  << Utils::GBKToUTF8(it.m_dataValue);
            //if(it.m_ginGroup == m_billValueGroup)
            names.append(Utils::GBKToUTF8(it.m_dataValue));
            qDebug() << "获取到更新的名字"  << Utils::GBKToUTF8(it.m_dataValue);
        }
    }

    return names;
}

QStringList SZNRAsduParser::parseBillValueUnits(const QByteArray &packet)
{
    QStringList  units;
    SZNRAsduParser parser;
    vector<OneDataSetStruct> dataSets =  parser.parseASDU10AllValue(packet);
    QString billValueGroup = "03";
    foreach (OneDataSetStruct it, dataSets)
    {
        // qDebug() << "组号 " << it.m_ginGroup.toInt(nullptr,16) << ", 汉字表示： "  << Utils::GBKToUTF8(it.m_dataValue);
        //if(it.m_ginGroup == m_billValueGroup)

        if ( Utils::GBKToUTF8(it.m_dataValue) == " " || Utils::GBKToUTF8(it.m_dataValue) == "" )
        {
            units.append("无");
        }
        else
        {
            units.append(Utils::GBKToUTF8(it.m_dataValue));
        }

        qDebug() << "获取到单位："  << Utils::GBKToUTF8(it.m_dataValue);
    }

    return units;
}

QStringList SZNRAsduParser::parseBillDimension(const QByteArray &packet)
{
    QStringList m_billValueMinList,m_billValueMaxList,m_billValueStepList;
    // 解析接收的报文
    SZNRAsduParser parser;
    vector<OneDataSetStruct> dataSets =  parser.parseASDU10AllValue(packet);
    foreach (OneDataSetStruct it, dataSets)
    {
        qDebug() << "读取定值的最大最小值和步长"<< it.m_dataValue;
        if (it.m_dataNum =="03" || it.m_dataNum == "02" || it.m_dataNum == "01")
        {
            if( it.m_dataType == "06" || it.m_dataType == "07") {  // 浮点数或者短实数
                qDebug() << "浮点数量程： "<< Utils::parseFloatTypeMinMaxStep(it.m_dataValue);

                if (Utils::parseFloatTypeMinMaxStep(it.m_dataValue).count() == 3) {
                    m_billValueMinList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[0]);
                    m_billValueMaxList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[1]);
                    m_billValueStepList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[2]);
                }
                else if (Utils::parseFloatTypeMinMaxStep(it.m_dataValue).count() == 2) {
                    m_billValueMinList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[0]);
                    m_billValueMaxList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[1]);
                    m_billValueStepList.append("无");
                }
                else if (Utils::parseFloatTypeMinMaxStep(it.m_dataValue).count() == 1) {
                    m_billValueMinList.append("无");
                    m_billValueMaxList.append("无");
                    m_billValueStepList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue));
                }
            }
            else if ( it.m_dataType == "03" )   //无符号整数量程
            {
                qDebug() << "无符号整数量程：" << it.m_dataValue << it.m_dataWidth << Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16));
                QStringList dataValueList =  Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16));
                switch ( Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16)).count())
                {
                case 0 :
                    m_billValueMinList.append("no");
                    m_billValueMaxList.append("no");
                    m_billValueStepList.append("no");
                    break;
                case 1 :
                    m_billValueMinList.append("no");
                    m_billValueMaxList.append("no");
                    m_billValueStepList.append(dataValueList[0]);
                    break;
                case 2 :
                    m_billValueMinList.append(dataValueList[0]);
                    m_billValueMaxList.append(dataValueList[1]);
                    m_billValueStepList.append("no");
                    break;
                case 3:
                    m_billValueMinList.append( dataValueList[0]);
                    m_billValueMaxList.append( dataValueList[1]);
                    m_billValueStepList.append(dataValueList[2]);
                    break;
                }
            }
            else if( it.m_dataType == "04")
            {
                int intDataWidth = it.m_dataWidth.toUInt(nullptr,16);
                qDebug() << "整数量程：" << it.m_dataValue << it.m_dataWidth << Utils::parseIntTypeMinMaxStep(it.m_dataValue, intDataWidth);
                QStringList dataValueList = Utils::parseIntTypeMinMaxStep(it.m_dataValue, intDataWidth);
                switch ( dataValueList.count())
                {
                case 0 :
                    m_billValueMinList.append("no");
                    m_billValueMaxList.append("no");
                    m_billValueStepList.append("no");
                    break;
                case 1 :
                    m_billValueMinList.append("no");
                    m_billValueMaxList.append("no");
                    m_billValueStepList.append(Utils::hexStrToIntStr(dataValueList[0]));
                    break;
                case 2 :
                    m_billValueMinList.append(dataValueList[0]);;
                    m_billValueMaxList.append(dataValueList[1]);
                    m_billValueStepList.append("无");
                    break;
                case 3 :
                    m_billValueMinList.append( dataValueList[0]);
                    m_billValueMaxList.append( dataValueList[1] );
                    m_billValueStepList.append( dataValueList[2] );
                    break;
                }
            }
            else if (it.m_dataType == "01")  // ASCII8位码量程,都是不存在最大最小步长值的
            {
                if (Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue).count() ==0 )
                {
                    m_billValueMinList.append("无");
                    m_billValueMaxList.append("无");
                    m_billValueStepList.append("无");
                }
                else if (Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue).count() ==1 )
                {
                    QString  strList = Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
                    m_billValueMinList.append("无");
                    m_billValueMaxList.append("无");
                    m_billValueStepList.append(strList);
                }
                else if (Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue).count() ==2 )
                {
                    int width = it.m_dataWidth.toInt(nullptr,16);
                    QString  strList = Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
                    m_billValueMinList.append(Utils::mixCharToWord(strList,width)[0]);
                    m_billValueMaxList.append(Utils::mixCharToWord(strList,width)[1]);
                    m_billValueStepList.append("无");
                }
                else
                {
                    int width = it.m_dataWidth.toInt(nullptr,16);
                    QString  strList = Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
                    // 将strList按照 单个宽度进行分割
                    qDebug() << "ASCII8位码量程：" <<Utils::mixCharToWord(strList,width);
                    m_billValueMinList.append(Utils::mixCharToWord(strList,width)[0]);
                    m_billValueMaxList.append(Utils::mixCharToWord(strList,width)[1]);
                    m_billValueStepList.append(Utils::mixCharToWord(strList,width)[2]);
                }
            }
        }
        else {  // 没有量程
            m_billValueMaxList.append("无");
            m_billValueMinList.append("无");
            m_billValueStepList.append("无");
        }
    }
    QStringList ret =  (m_billValueMinList + m_billValueMaxList + m_billValueStepList);

    return ret;
}

QStringList SZNRAsduParser::parseBillInfo(const int replyType, const QByteArray &packetAll)
{
    QStringList result;

    // 获取当前响应的组号
    QByteArray packet = packetAll.mid(POS_ASDU_RII, packetAll.count() - 16);
    qDebug() << packet << packet.mid(POS_ASDU_GROUPNO, 2);
    QString groupNo = Utils::hexNumToDecNum(packet.mid(POS_ASDU_GROUPNO, 2));
    qDebug() << "******* 解析table info ********* 组号 = " << groupNo;

    // 每一组一个 BillStruct 结构体来缓存数据


    qDebug() << "asdu 数据类型 = " << replyType;
    //  当非第一次请求的时候应该将 m_billTablesMap 清空

    switch (replyType)
    {
    case REPLY_TYPE_ALL_GROUP_TITLE:
        result = parseBillTitles(packet);
        break;
    case REPLY_READ_SETTINGS_NAME:
        result = parseBillValueNames(packet);
        qDebug() << "********定值名字结果********" << result;
        m_billTablesMap[groupNo].billNameList.append(result);
        break;
    case REPLY_READ_SETTINGS_CURRVALUE:
        result = parseBillRealValue(packet);
        qDebug() << "第 " << groupNo << " 组"  << "将添加解析实际值的结果 = " << result;
        m_billTablesMap[groupNo].billRealValueList.append(result);
        m_billTablesMap[groupNo].groupNo = groupNo;
        m_billTablesMap[groupNo].billTypeList.append(parseBillValueDataTypes(packet));  //在解析定值同时解析定值数据类型
        break;
    case REPLY_READ_DEFAULTVALUE:
        result = parseBillDefaultValue(packet);
        m_billTablesMap[groupNo].billDefaultValueList.append(parseBillDefaultValue(packet));
        break;
    case REPLY_READ_SETTINGS_MIN:
        result = parseBillDimension(packet);
        qDebug() << " 解析定值量程 -- " << result;
        m_billTablesMap[groupNo].billMinList.append(result.mid(0, result.count()/3));
        m_billTablesMap[groupNo].billMaxList.append(result.mid((result.count()/3), result.count()/3));
        m_billTablesMap[groupNo].billStepsList.append(result.mid(( 2 * result.count()/3), result.count()/3 ));
        break;
    case REPLY_READ_SETTINGS_UNIT:
        result = parseBillValueUnits(packet);
        m_billTablesMap[groupNo].billUnitList.append(result);
        break;
    case REPLY_READ_SETTINGS_AREA:
        result = parseBillArea(packet);
        break;
    default:
        result = parseBillUnkown(packet);   // 未知类型
        break;
    }

    return result;
}

QMap<QString, BillTableStruct> SZNRAsduParser::getBillTableMap()
{
    qDebug() << "asdu 层成员函数中 =  " << m_billTablesMap.count() << m_billTablesMap.keys();

    foreach( BillTableStruct  it, m_billTablesMap ) {
        qDebug() << "SZNRAsduParser 组号 =  " << it.groupNo << it.billRealValueList;
    }

    return m_billTablesMap;
}

void SZNRAsduParser::clearBillTableBuffer()
{
    m_billTablesMap.clear();
}

void SZNRAsduParser::getBillRelationGroupNos(QMap<QString, QString> &groupNoAndName)
{
    QMap<QString,QString>::iterator it;
    for (it = groupNoAndName.begin(); it!=groupNoAndName.end(); ++it)
    {
        if (it.value().contains(KEY_BILLGROUP_NAME) || it.key().contains("02"))              // 展示只关心定值
        {
            qDebug() << "发现一个定值组 = " << it.key();
            m_billValueGroupsNo.push_back(it.key());
            struct BillTableStruct tmpTable;
            tmpTable.groupName = it.value();
            tmpTable.groupNo = it.key();
            m_billTables.append(tmpTable);
            qDebug() << " 组号 =  " << it.key();
            m_billTablesMap[it.key()] = tmpTable;       //初始化保存有关定值组具体各项信息的空间
        }
        else if ( it.value().contains("系统") )
        {
            m_deviceSysGroupNo = it.key();
        }
        else if ( it.value().contains("压板") )
        {
            m_ybGroupNo = it.key();
        }
    }

    qDebug() << "asdu 层定值组个数" << m_billTablesMap.count();
}

QStringList SZNRAsduParser::parseBillTitles(const QByteArray &packet)
{
    vector<OneDataSetStruct> dataSets = parseASDU10AllValue(packet);
    QStringList titiles;
    QStringList groupNoes;
    foreach (OneDataSetStruct it, dataSets)
    {
        groupNoes.push_back(Utils::hexNumToDecNum(it.m_ginGroup));      // 同时添加到组号
        // 进行简单的判断确认数据正确
        titiles.push_back(Utils::GBKToUTF8(it.m_dataValue));
        qDebug() << "添加一个组号和一个" << Utils::hexNumToDecNum(it.m_ginGroup) << Utils::GBKToUTF8(it.m_dataValue) ;
    }

    getBillTitleGroupNo(packet);

    return groupNoes + titiles;       // 组号 + 名字
}

QStringList SZNRAsduParser::parseBillArea(const QByteArray &packet)
{
    vector<OneDataSetStruct> dataSets = parseASDU10AllValue(packet);
    QStringList areaValue;
    foreach (OneDataSetStruct it, dataSets)
    {
        // qDebug() << "定值区号： " << Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16));
        areaValue.append(Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16)));
    }

    return areaValue;
}

QStringList SZNRAsduParser::parseBillDefaultValue(const QByteArray &packet)
{
    // 实际数据,缺省值，准确度
    // 解析接收的报文
    vector<OneDataSetStruct> dataSets =  parseASDU10AllValue(packet);
    QString billValueGroup = "03";
    QStringList billValueDefaultList;         // 存放默认值
    foreach (OneDataSetStruct it, dataSets)
    {


        ///qDebug() << "数据" << ++i << it.m_dataValue;
        if (it.m_dataType == "00")
        {
            qDebug() << "数据无所对应的类型";
            billValueDefaultList.append(" ");
        }
        else if (it.m_dataType == "01")
        {
            qDebug() << "数据类型为 OS8ASCII" << Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
            billValueDefaultList.append(Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue));
        }
        else if (it.m_dataType == "03")
        {
            qDebug() << "数据类型为无符号整数" << (Utils::reverseStr(it.m_dataValue).toUInt(nullptr, 16));
            billValueDefaultList.append(QString::number((Utils::reverseStr(it.m_dataValue).toUInt(nullptr, 16))));
        }
        else if(it.m_dataType == "04")
        {
            //  qDebug() << "数据类型为整形数" << Utils::hexStrToIntStr(it.m_dataValue);
            billValueDefaultList.append(Utils::hexStrToIntStr(it.m_dataValue));
        }
        else if( it.m_dataType == "06")
        {
            qDebug() << "数据类型为浮点数" << Utils::hexStrToFloat(it.m_dataValue);     // IEEE 754 短实数
            billValueDefaultList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
        }
        else if (it.m_dataType == "07")      // 数据类型为短实数
        {
            qDebug() <<"数据类型为短实数: " << Utils::hexStrToFloat(it.m_dataValue);
            billValueDefaultList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
        }
        else if (it.m_dataType == "09")
        {
            qDebug() << "数据类型为双点信息" << (Utils::reverseStr(it.m_dataValue)).toInt();        // bool 类型值
            billValueDefaultList.append(Utils::reverseStr(it.m_dataValue));
        }
        else
        {
            if (it.m_dataType == "10")
            {
                qDebug() << "数据类型为单点信息";
            }
            else if (it.m_dataType == "0C")
            {
                qDebug() << "数据类型为带品质描述的被测值";
            }
            else if (it.m_dataType == "13")
            {
                qDebug() << "数据类型为带时标的报文";
            }
            else if (it.m_dataType == "18")
            {
                qDebug() << "数据类型为数据结构";
            }
            else if (it.m_dataType == "CB")
            {
                qDebug() << "数据类型为带7字节的时标报文";
            }
            else if (it.m_dataType == "CC")
            {
                qDebug() << "数据类型为带相对时间的7字节时标报文";
            }
            else if(it.m_dataType == "00")
            {
                qDebug() << "数据类型为无所确定的类型";
            }
        }
    }

    return billValueDefaultList;
}

QStringList SZNRAsduParser::parseBillRealValue(const QByteArray &packet)
{
    // 实际数据,缺省值，准确度
    // 解析接收的报文
    qDebug() << "parseBillRealValue  开始解析实际值 = " << packet;
    vector<OneDataSetStruct> dataSets = parseASDU10AllValue(packet);
    QStringList billValueList;         // 存放默认值
    foreach (OneDataSetStruct it, dataSets)
    {
        if (it.m_dataType == "00")
        {
            qDebug() << "数据无所对应的类型";
            billValueList.append(" ");
        }
        else if (it.m_dataType == "01")
        {
            qDebug() << "数据类型为 OS8ASCII" << Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
            billValueList.append(Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue));
        }
        else if (it.m_dataType == "03")
        {
            qDebug() << "数据类型为无符号整数" << (Utils::reverseStr(it.m_dataValue).toUInt(nullptr, 16));
            billValueList.append(QString::number((Utils::reverseStr(it.m_dataValue).toUInt(nullptr, 16))));
        }
        else if(it.m_dataType == "04")
        {
            //qDebug() << "数据类型为整数" << Utils::hexStrToIntStr(it.m_dataValue);
            billValueList.append( Utils::hexStrToIntStr(it.m_dataValue));
        }
        else if( it.m_dataType == "06")
        {
            qDebug() << "数据类型为浮点数" << Utils::hexStrToFloat(it.m_dataValue);     // IEEE 754 短实数
            billValueList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
        }
        else if (it.m_dataType == "07")      // 数据类型为短实数
        {
            qDebug() <<"数据类型为短实数: " << Utils::hexStrToFloat(it.m_dataValue);
            billValueList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
        }
        else if (it.m_dataType == "09")
        {
            qDebug() << "数据类型为双点信息" << (Utils::reverseStr(it.m_dataValue)).toInt();        // bool 类型值
            billValueList.append(Utils::reverseStr(it.m_dataValue));
        }
        else if (it.m_dataType == "0a") {
            qDebug() << "数据类型为单点信息" << (Utils::reverseStr(it.m_dataValue)).toInt();        // bool 类型值
            billValueList.append(Utils::reverseStr(it.m_dataValue));
        }
        else
        {
            if (it.m_dataType == "10")
            {
                qDebug() << "数据类型为单点信息";
            }
            else if (it.m_dataType == "0C")
            {
                qDebug() << "数据类型为带品质描述的被测值";
            }
            else if (it.m_dataType == "13")
            {
                qDebug() << "数据类型为带时标的报文";
            }
            else if (it.m_dataType == "18")
            {
                qDebug() << "数据类型为数据结构";
            }
            else if (it.m_dataType == "CB")
            {
                qDebug() << "数据类型为带7字节的时标报文";
            }
            else if (it.m_dataType == "CC")
            {
                qDebug() << "数据类型为带相对时间的7字节时标报文";
            }
            else if(it.m_dataType == "00")
            {
                qDebug() << "数据类型为无所确定的类型";
            }
        }
    }

    QString groupNo = dataSets.at(0).m_ginNo;   // 获取组号
    m_billTablesMap[groupNo].billRealValueList.append(billValueList);
    m_billTablesMap[groupNo].groupNo = groupNo;

    return billValueList;
}

QStringList SZNRAsduParser::parseBillUnkown(const QByteArray &packet)
{
    QStringList unknow = {"0"};
    return unknow;
}

// 解析定值数据类型，在解析默认值的时候就可以确认
QStringList SZNRAsduParser::parseBillValueDataTypes(const QByteArray &packet)
{
    // 实际数据,缺省值，准确度
    // 解析接收的报文
    vector<OneDataSetStruct> dataSets = parseASDU10AllValue(packet);
    QString billValueGroup = "03";
    QStringList dataTypes;         // 存放默认值
    foreach (OneDataSetStruct it, dataSets)
    {
        qDebug() << "数据对应的类型 = " << it.m_dataType;
        dataTypes.append(it.m_dataType);
    }

    return dataTypes;
}

void  SZNRAsduParser::getBillTitleGroupNo(const QByteArray &packet)
{
    vector<OneDataSetStruct> dataSets = parseASDU10AllValue(packet);
    foreach (OneDataSetStruct it, dataSets)
    {
        m_groupNoNameMap [Utils::hexNumToDecNum(it.m_ginGroup)] = Utils::GBKToUTF8(it.m_dataValue);

        qDebug() << "添加一个组号和一个" << Utils::hexNumToDecNum(it.m_ginGroup) << Utils::GBKToUTF8(it.m_dataValue);
    }

    // 获取定值组组号信息
    //getBillRelationGroupNos(m_groupNoNameMap);
}

void SZNRAsduParser::showDataSets(vector<OneDataSetStruct> &dataSets)
{
    //根据数据类型来分
    int i=0;
    foreach (OneDataSetStruct it, dataSets)
    {
        // 定值的名称描述
        if (it.m_kod == "0A")
        {
            qDebug() << "数据 " << ++i << it.m_dataValue;
            qDebug() << "组号 " << it.m_ginGroup.toInt(nullptr, 16) << ", 汉字表示： "  << Utils::GBKToUTF8(it.m_dataValue);
            m_billValueName.append(Utils::GBKToUTF8(it.m_dataValue));
        }
         // 实际数据,缺省值，准确度
        else if (it.m_kod == "01" || it.m_kod == "02" || it.m_kod == "05")
        {
              qDebug() << "数据" << ++i << it.m_dataValue;

            if (it.m_dataType == "00")
            {
                qDebug() << "数据无所对应的类型";
                m_billValueDefaultList.append(" ");
            }
            else if (it.m_dataType == "01")
            {
                qDebug() << "数据类型为 OS8ASCII" << Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
                m_billValueDefaultList.append(Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue));
            }
            else if (it.m_dataType == "03")
            {
                qDebug() << "数据类型为无符号整数" << (Utils::reverseStr(it.m_dataValue).toUInt(nullptr,10));
                m_billValueDefaultList.append(QString::number((Utils::reverseStr(it.m_dataValue).toUInt(nullptr,10))));
            }
            else if (it.m_dataType == "06")
            {
                qDebug() << "数据类型为浮点数" << Utils::hexStrToFloat(it.m_dataValue);     // IEEE 754 短实数
                m_billValueDefaultList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
            }
            else if (it.m_dataType == "07")      // 数据类型为短实数
            {
                qDebug() <<"数据类型为短实数: " << Utils::hexStrToFloat(it.m_dataValue);
                m_billValueDefaultList.append(QString::number(Utils::hexStrToFloat(it.m_dataValue)));
            }
            else if (it.m_dataType == "09")
            {
                qDebug() << "数据类型为双点信息" << (Utils::reverseStr(it.m_dataValue)).toInt();        // bool 类型值
                m_billValueDefaultList.append(Utils::reverseStr(it.m_dataValue));
            }
            else if (it.m_dataType == "0a")
            {
                qDebug() << "数据类型为单点信息";
            }
            else if (it.m_dataType == "0C")
            {
                qDebug() << "数据类型为带品质描述的被测值";
            }
            else if (it.m_dataType == "13")
            {
                qDebug() << "数据类型为带时标的报文";
            }
            else if (it.m_dataType == "18")
            {
                qDebug() << "数据类型为数据结构";
            }
            else if (it.m_dataType == "CB")
            {
                qDebug() << "数据类型为带7字节的时标报文";
            }
            else if (it.m_dataType == "CC")
            {
                qDebug() << "数据类型为带相对时间的7字节时标报文";
            }
            else if(it.m_dataType == "00")
            {
                qDebug() << "数据类型为无所确定的类型";
            }
        }
        //最大值最小值步长
        else if (it.m_kod == "03")
        {
            qDebug() << "读取定值的最大最小值和步长"<< it.m_dataValue;
            if (it.m_dataNum =="03" || it.m_dataNum == "02")
            {
                if( it.m_dataType == "06" || it.m_dataType == "07") // 浮点数或者短实数
                {
                    qDebug() << "浮点数量程： "<<Utils::parseFloatTypeMinMaxStep(it.m_dataValue);
                    m_billValueMinList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[0]);
                    m_billValueMaxList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[1]);
                    m_billValueStepList.append(Utils::parseFloatTypeMinMaxStep(it.m_dataValue)[2]);
                }
                else if ( it.m_dataType == "03" )   // 整数量程
                {
                    qDebug() << "整数量程：" << it.m_dataValue << it.m_dataWidth << Utils::parseUIntType(it.m_dataValue, it.m_dataWidth.toUInt(nullptr,16));

                    switch ( Utils::parseIntTypeMinMaxStep(it.m_dataValue,it.m_dataWidth.toUInt(nullptr, 16)).count())
                    {
                        case 0 :
                        m_billValueMinList.append("no");
                        m_billValueMaxList.append("no");
                        m_billValueStepList.append("no");
                        break;
                    case 1 :
                        m_billValueMinList.append("no");
                        m_billValueMaxList.append("no");
                        m_billValueStepList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[0]);
                        break;
                    case 2 :
                        m_billValueMinList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[0]);
                        m_billValueMaxList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[1]);
                        m_billValueStepList.append("no");
                        break;
                    case 3:
                        m_billValueMinList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[0]);
                        m_billValueMaxList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[1]);
                        m_billValueStepList.append(Utils::parseUIntType(it.m_dataValue,it.m_dataWidth.toUInt(nullptr,16))[2]);
                        break;
                    }
                }
                else if (it.m_dataType == "01")  // ASCII8位码
                {
                    if(Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue).count() !=3)
                    {
                        m_billValueMinList.append(" ");
                        m_billValueMaxList.append(" ");
                        m_billValueStepList.append(" ");
                    }
                    int width = it.m_dataWidth.toInt(nullptr,16);
                    QString  strList = Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue);
                    // 将strList按照 单个宽度进行分割
                    qDebug() << "ASCII8位码量程：" <<Utils::mixCharToWord(strList,width);
                    this->m_billValueMinList.append(Utils::mixCharToWord(strList,width)[0]);
                    m_billValueMaxList.append(Utils::mixCharToWord(strList,width)[1]);
                    m_billValueStepList.append(Utils::mixCharToWord(strList,width)[2]);
                }
            }
        }
        // 读取单位
        else if (it.m_kod == "09")
        {
          // qDebug() << "单位" <<  Utils::mixCharToWord(Utils::parseASCII8BTypeMinMaxStepUnit(it.m_dataValue),it.m_dataWidth.toInt(nullptr,16));
           qDebug() << "单位 GBKTOUTF8 :" << Utils::GBKToUTF8(it.m_dataValue);
           m_billValueUinitList.append( Utils::GBKToUTF8(it.m_dataValue) );
        }
    }
}

QString SZNRAsduParser::findGroupNoByGroupName(const QString &groupName, vector<OneDataSetStruct> &dataSets)
{
    foreach (OneDataSetStruct it, dataSets)
    {
        if (it.m_kod == "0A" && Utils::GBKToUTF8(it.m_dataValue) == groupName )
        {
            return it.m_ginGroup;
        }
    }
    qDebug() << "not find the group.";

    return nullptr;
}

